package newx.com.control
{
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.SecurityErrorEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	
	import newx.com.loader.SwfLoader;
	import newx.utils.debug.IO;

	/** 纯AS静态悬浮提示工具   			version 1.0
	 * 				(由于实时更换背景的可能性比较小，因此没有对加载进来的背景进行储存)
	 * 	@author yangwen				2009.04.13
	 * 
	 * 			该工具类在一个swf播放器中始终只存在一个实例
	 *  
	 *  通用设置（使用下面的设置的时候会改变全局的显示效果）
	 * 
	 * 			作用							方法
	 * 		1.设置背景颜色				AsToolTip.setBgColor		(新的十六进制颜色色值);
	 * 		2.设置边框线条颜色			AsToolTip.setBorderColor	(新的十六进制颜色色值);
	 * 		3.设置文本颜色				AsToolTip.setTextColor		(新的十六进制颜色色值);
	 * 		4.设置背景透明度			AsToolTip.setBgAlpha		(新的透明度值);
	 * 		5.设置背景图片				AsToolTip.setBgImageUrl		(背景地址);
	 * 		6.设置缩放区域				AsToolTip.setBgScale9Grid	(缩放区域);  				（当背景设置正确后才能选择使用）
	 * 
	 * 		finale 隐藏提示框			AsToolTip.hide();
	 * 
	 * 		*******   		注意 		********
	 * 			1.若中途需要修改以上的2个或2个以上的属性，建议直接重新初始化该类 即调用 AsToolTip.Init(...argc)
	 * 			2.设置背景图片且成功加载后，自动绘制的背景颜色及线条将不存在.其他情况下，都会使用定义的配置颜色进行绘制背景
	 * 			3.更换或初次设置图片的时候，不会立即显示新的背景图片，当再次调用AsToolTip.ShowInfo(...argc)的时候才会显示
	 * 		*******
	 * 
	 *  使用方法有2种
	 * 
	 * 	方法一使用步骤
	 * 		1.在主文档类中先初始化该类 即直接调用 		AsToolTip.Init(...argc);
	 * 		2.在要显示悬浮提示的时候调用				AsToolTip.ShowInfo(...argc);
	 * 
	 *  方法二
	 * 		直接使用  AsToolTip.ShowInfo(...argc) ，此方法下的悬浮框将使用默认的颜色配置
	 * 
	 * @editor wangpg	2011.03.24
	 * 	将此类改变为一个Tips管理类，储存并创建NxToolTipsNotePanel类用于显示。
	 * 
	 *  增加使用方法
	 * 
	 * 	方法三
	 * 		直接使用  AsToolTip.ShowInfoArray(...argc) , 此方法下的悬浮框将使用默认的颜色设置，可以显示多提示信息
	 * 	
	 */	
	
	public class NxToolTips extends Sprite
	{		
		private static var hasConstruct		:Boolean		=	false;
		private static var mainNotePanel			:NxToolTips;
		private static var _stage				:Stage;
		private static var bgColor			:uint			=	0x000000;		//背景颜色
		private static var borderColor		:uint			=	0xccff00;		//线条颜色
		private static var textColor			:uint			=	0xffff99;		//0xf9f9f9;	//字体颜色
		private static var bgAlpha			:Number			=	0.7;			//背景透明度
		private static var bgImageData		:DisplayObject	=	null;
		private static var bgScale9Grid		:Rectangle		=	null;
		private static var notePanels		:Array 			= 	new Array();	//NxToolTipsNotePanel 集合
		private static var itemPics			:Array			=	new Array();	//装备预览图片集合
		private static var normalState		:Boolean 		=	true;			//多提示框正常位置
		private static var tipMaxWidth		:uint			=	240;				//tips最大宽度
		private static var itemSPArray		:Array			=	new Array();
		private var rate		:int		=	5;		
		private var rx			:int		=	0;
		private var dy			:int		=	0;
		
		/** 初始化基本设置，一般在主类最前面使用
		 * 
		 * @param _client			显示对象的载体
		 * @param _bgColor			背景颜色
		 * @param _borderColor		边框线条颜色
		 * 
		 * @param _bgImageUrl		背景图片地址（可以是swf）,如果不设置，则背景为纯色绘制底图
		 * @param _bgScale9Grid		如果设置了正确的背景地址（能正确访问到的图片或者swf地址），
		 * 							那么在背景加载完成后，则自动按这个rectangle配置缩放区域，不设置值的时候将按默认的值进行缩放
		 * 							默认值为大小是 50*20 的源文件，缩放区域是 (5,5,40,10);
		 * @param _textColor		文字颜色
		 * @param _bgAlpha			透明度
		 * 
		 */		
		public static function Init(	_client:DisplayObject,tipWidth:uint = 240,  _bgColor:uint = 0x000000,	_borderColor:uint = 0xccff00,
										_bgImageUrl:String = null,	_bgScale9Grid:Rectangle = null,
										_textColor:uint = 0xf9f9f9,	_bgAlpha:Number = 0.7	):void
		{
			tipMaxWidth	=	tipWidth;
			
			NxToolTips.setBgColor			(_bgColor);
			NxToolTips.setBorderColor		(_borderColor);
			NxToolTips.setTextColor			(_textColor);
			NxToolTips.setBgAlpha			(_bgAlpha);
			NxToolTips.setBgImageUrl			(_bgImageUrl);
			NxToolTips.setBgScale9Grid		(_bgScale9Grid);
			
			if(!NxToolTips._stage)
			{
				if(_client.stage)
				{
					NxToolTips.mainNotePanel		=	new NxToolTips();
					NxToolTips._stage		=	_client.stage;
					NxToolTips._stage.addChild	(NxToolTips.mainNotePanel);
				}
				else
				{
					throw new Error("初始化失败, " + _client + " 不在显示列表中，请先将 " +
									_client + " 添加到显示列表中!");
				}
			}
		}
		
		/** 设置提示框背景的颜色
		 * 
		 * @param c				新的十六进制颜色色值
		 * 
		 */		
		public static function setBgColor(c:uint):void
		{
			NxToolTips.bgColor				=	c;
		}
		
		/** 设置边框线条颜色
		 * 
		 * @param c				新的十六进制颜色色值
		 * 
		 */		
		public static function setBorderColor(c:uint):void
		{
			NxToolTips.borderColor			=	c;
		}
		
		/** 设置文本的颜色
		 * 
		 * @param c				新的十六进制颜色色值
		 * 
		 */		
		public static function setTextColor(c:uint):void
		{
			NxToolTips.textColor				=	c;
		}
		
		/** 设置背景透明度
		 * 
		 * @param c				新的十六进制颜色色值
		 * 
		 */		
		public static function setBgAlpha(c:Number):void
		{
			c								=	Math.abs(c);
			if(c > 1)
			{
				c							=	(c % 101) / 100;
			}
			NxToolTips.bgAlpha				=	c;
		}
		
		/** 设置背景图片
		 * 
		 * @param url			背景图片的路径，最好是绝对路径，默认图片大小为50*20，默认缩放区域为(5,5,40,10)便于拉伸
		 * 
		 */		
		public static function setBgImageUrl(url:String):void
		{
			if(!url)
			{
				return;
			}
			NxToolTips.bgImageData			=	null;
			var ld		:Loader				=	new Loader();
			ld.contentLoaderInfo.addEventListener(Event.COMPLETE,						loadBgCom);
			ld.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,				loadError);
			ld.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,	loadError);
			ld.load(new URLRequest(url));
		}
		
		private static function loadBgCom(e:Event):void
		{
			NxToolTips.bgImageData			=	e.target.content;
			if(NxToolTips.bgImageData is Bitmap)
			{
//				IO.traceLog('   ',AsToolTip,'设置使用 位图 背景');
			}
			else
			{
//				IO.traceLog('   ',AsToolTip,'设置使用 swf 背景');
				NxToolTips.bgImageData.scale9Grid	=	NxToolTips.bgScale9Grid;
			}
		}
		
		private static function loadError(e:Event):void
		{
			IO.traceLog('    加载背景失败');
		}
		
		/** 设置背景缩放区域
		 * 
		 * @param _bgScale9Grid			背景的缩放区域，默认图片大小为50*20，默认缩放区域为(5,5,40,10)便于拉伸
		 * 
		 */		
		public static function setBgScale9Grid(_bgScale9Grid:Rectangle):void
		{
			if(!_bgScale9Grid)
			{
				NxToolTips.bgScale9Grid		=	new Rectangle(5,5,40,10);
			}
			else
			{
				NxToolTips.bgScale9Grid		=	_bgScale9Grid;
			}
		}
		
		/** 将目标绑定鼠标滑过和离开的事件显示信息(适用于提示信息固定不变的)
		 * 
		 * @param target				包绑定的对象
		 * @param content				要显示的提示信息
		 * 
		 */		
		public static function BindTip(target:DisplayObject,content:String):void
		{
			
			var onover		:Function	=	function(e1:MouseEvent):void
			{
				NxToolTips.ShowInfo(content);
			}
			
			var onout		:Function	=	function(e2:MouseEvent):void
			{
				NxToolTips.hide();
			}
			
			var removeBind	:Function	=	function(e3:Event):void
			{
				e3.currentTarget.removeEventListener(MouseEvent.ROLL_OVER,		onover);
				e3.currentTarget.removeEventListener(MouseEvent.MOUSE_OVER,		onover);
				e3.currentTarget.removeEventListener(MouseEvent.ROLL_OUT,		onout);
				e3.currentTarget.removeEventListener(MouseEvent.MOUSE_OUT,		onout);
				e3.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE,	removeBind);
				onover					=	null;
				onout					=	null;
				removeBind				=	null;
				NxToolTips.hide(true);
			}
			
			target.addEventListener(MouseEvent.ROLL_OVER,						onover);
			target.addEventListener(MouseEvent.MOUSE_OVER,						onover);
			target.addEventListener(MouseEvent.ROLL_OUT,						onout);
			target.addEventListener(MouseEvent.MOUSE_OUT,						onout);
			target.addEventListener(Event.REMOVED_FROM_STAGE,					removeBind);
		}
		
		/** 静态方法 显示提示信息
		 * 
		 * @param content			信息内容
		 * @param followMouse		是否跟随鼠标，如果不跟随鼠标，则必须设置stagePosition参数
		 * @param stagePosition		全局（舞台）坐标点  (此参数只在followMouse设置为false的时候才有效)
		 * 
		 */
		public static function ShowInfo(content:String,followMouse:Boolean = true,stagePosition:Point = null,itemURL:String = ""):void
		{
			if(!NxToolTips._stage)
			{	IO.traceLog("    提示信息:",content);
				IO.traceLog("还没对 AsToolTip 进行初始化，请先调用 AsToolTip.Init(...argc) 对AsToolTip进行初始化");
				return;
			}
			
			if(!content || 1 > content.length)
			{
				return;
			}
			
			/** notePanels 是否存在NxToolTipsNotePanel **/
			var temp:NxToolTipsNotePanel;			
			if(NxToolTips.notePanels.length > 1)
			{
				temp = NxToolTips.notePanels[0];
				temp.x = 0;
			}
			else
			{				
				temp = new NxToolTipsNotePanel(textColor, 0);				
				NxToolTips.notePanels.push(temp);
			}
			var item:NxToolTipsPicPanel;
			if (itemURL != "") 
			{
				
				if (NxToolTips.itemPics.length > 1) 
				{
					item	=	NxToolTips.itemPics[0];
				}
				else
				{
					item	=	new NxToolTipsPicPanel();
					NxToolTips.itemPics.push(item);
				}
				item.setPic(itemURL);
			}
			NxToolTips.mainNotePanel.showText(temp,content,followMouse,stagePosition);
			NxToolTips.mainNotePanel.addChild(temp);
			if (item != null) 
			{
				item.x	=	item.y	=	0;
				temp.addChild(item);
			}
			NxToolTips.mainNotePanel.visible = true;
			normalState = true;
		}
		
		/** 静态方法 显示多提示信息
		 * 
		 * @param contents			信息内容数组
		 * 
		 */		
		public static function ShowInfoArray(contents:Array,followMouse:Boolean = true,stagePosition:Point = null):void
		{
			if(!NxToolTips._stage)
			{
				IO.traceLog("还没对 AsToolTip 进行初始化，请先调用 AsToolTip.Init(...argc) 对AsToolTip进行初始化");
				return;
			}
			
			if(!contents || 1 > contents.length)
			{
				return;
			}
			
			NxToolTips.mainNotePanel.visible = false;
			
			/** 这里创建并储存显示对象 notePanels **/			
			var num:int = contents.length;
			var pos:int = 0;
			var temp:NxToolTipsNotePanel;
			for(var i:int=0; i < num; ++i)
			{
				if(i+1 > NxToolTips.notePanels.length)
				{
					temp = new NxToolTipsNotePanel(textColor, pos);
					NxToolTips.notePanels.push(temp);
				}
				else
				{
					temp = NxToolTips.notePanels[i] as NxToolTipsNotePanel;
					temp.x = pos;
				}				
				NxToolTips.mainNotePanel.showText(temp,contents[i],followMouse,stagePosition);
 				NxToolTips.mainNotePanel.addChild(temp);
				/** 显示位置 **/
				pos += temp.width + 5;
			}
			normalState = true;
			NxToolTips.mainNotePanel.resetPos();
			NxToolTips.mainNotePanel.visible = true;
		}
		
		/** 隐藏 AsToolTip */
		public static function hide(...rest):void
		{
			while(NxToolTips.mainNotePanel.numChildren > 0)
			{
				NxToolTips.mainNotePanel.removeChildAt(0);
			}
			for (var i:int = 0; i < NxToolTips.itemPics.length; i++) 
			{
				var itemPic:NxToolTipsPicPanel	=	NxToolTips.itemPics[i] as NxToolTipsPicPanel;
				itemPic.clearPic();
			}
			NxToolTips.mainNotePanel.hideText();
		}
		
		public function NxToolTips()
		{
			if(NxToolTips._stage || NxToolTips.hasConstruct)
			{
				throw new Error(" ------- AsToolTip 已经在内存中存在，不能重复构建 AsToolTip -------");
				return;
			}
			
			NxToolTips.hasConstruct	=	true;
			this.mouseChildren		=	false;
			this.mouseEnabled		=	false;
			this.visible			=	false;
			this.addEventListener(Event.ADDED_TO_STAGE,		init);
			this.addEventListener(Event.REMOVED_FROM_STAGE,	deleteEvent);
		}
		
		/** 重绘基本界面
		 * 
		 * @param argc			参数暂时不处理
		 * 
		 */				
		private final function init(...argc):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE,		init);
		}
		
		private final function deleteEvent(e:Event):void
		{
			NxToolTips._stage		=	null;
			NxToolTips.hasConstruct	=	false;
			NxToolTips.bgImageData	=	null;
			NxToolTips.bgScale9Grid	=	null;
			this.removeEventListener(Event.ENTER_FRAME,		effIn);
		}
		
		/** 获取当前提示框的宽度
		 * 
		 * @return 
		 * 
		 */		
		public static function getWidth():Number
		{
			if(mainNotePanel)
			{
				return mainNotePanel.width;
			}
			return 0;
		}
		
		/** 获取当前提示框的高度
		 * 
		 * @return 
		 * 
		 */		
		public static function getHeight():Number
		{
			if(mainNotePanel)
			{
				return mainNotePanel.height;
			}
			return 0;
		}
		
		/** 移动提示框的位置
		 * 
		 * @param X
		 * @param Y
		 * 
		 */		
		public static function moveTo(X:Number,Y:Number):void
		{
			if(mainNotePanel)
			{
				mainNotePanel.x					=	X;
				mainNotePanel.y					=	Y;
			}
		}
		
		/** 实例显示提示信息的接口
		 * 
		 * @param content			信息内容
		 * @param followMouse		是否跟随鼠标，如果不跟随鼠标，则必须设置stagePosition参数
		 * @param stagePosition		全局（舞台）坐标点  (此参数只在followMouse设置为false的时候才有效)
		 * 
		 */	
		public final function showText(temp:NxToolTipsNotePanel,str:String,followMouse:Boolean = true,stagePosition:Point = null):void
		{
			temp.printText(str,tipMaxWidth);
			if(!NxToolTips.bgImageData)
			{
				/***
				 * 如果背景图片没有加载完成或者没设置背景图片，则自动填充先前设置过的背景颜色
				 * */
				temp.drawBg(borderColor,bgColor,rate);
			}
			else
			{
				/***
				 * 如果有背景图片，则自动填充背景图片
				 * */
				temp.constructBitmapBg(bgImageData,bgScale9Grid);
			}
			temp.setAphla(NxToolTips.bgAlpha);
			
			temp.visible			=	true;
						
			this.removeEventListener(Event.ENTER_FRAME,		effIn);
			
			if(followMouse)
			{
				this.addEventListener(Event.ENTER_FRAME,		effIn);
			}
			else
			{
				if(!stagePosition)
				{
					this.x			=	(_stage.stageWidth - this.width) / 2;
					this.y			=	(_stage.stageHeight - this.height) / 2;
				}
				else
				{
					this.x			=	stagePosition.x;
					this.y			=	stagePosition.y;
				}
				this.alpha			=	1;
				this.visible		=	true;
			}
			this.parent.setChildIndex(this,this.parent.numChildren - 1);
		}
		
		private static function getPicSpace(url:String):Sprite
		{
			var temp:Sprite	=	new Sprite();
			temp.graphics.beginFill(0x800000);
			temp.graphics.drawRect(0, 0, 10, 10);
			temp.graphics.endFill();
			if (url != "") 
			{
				var tempPic:NxClip	=	new NxClip();
				tempPic.x							=	150;
				tempPic.y							=	200;
				temp.addChild(tempPic);
				SwfLoader.StartLoad(url,null,onComplete);
				function onComplete(val:DisplayObject, pList:Array):void
				{
					var mc:MovieClip	 			= new MovieClip();
					mc 								= (val as MovieClip);
					tempPic.source					=	mc;
				}
			}
			return temp;
		}
		private final function resetPos():void
		{
			
			this.x					=	this.stage.mouseX + 24;
			this.y					=	this.stage.mouseY + 24;
			
			this.rx					=	int(this.stage.stageWidth - this.width - 2);
			this.dy					=	int(this.stage.stageHeight - this.height - 10);
			
			var needChangePos:Boolean = false;
			if(this.x > this.rx)
			{
				this.x				=	int(this.stage.mouseX - this.width - 12);
				needChangePos = true;
			}
			if(this.x < 0)
			{
				this.x				=	12;
			}
			if(this.y > this.dy)
			{
				this.y				=	this.dy;
			}
			
			/** 多提示框改变显示位置 **/
			var npCount:int = NxToolTips.mainNotePanel.numChildren; 
			if(npCount < 2)
			{
				return;
			}
			var temp:NxToolTipsNotePanel;
			var pos:int = 0;
			if(needChangePos)
			{
				/** 显示框移动，第一notePanel始终离鼠标最近 **/
				if(!normalState){
					return;
				}
				for(var i:int=1; i < npCount; ++i)
				{
					temp = NxToolTips.notePanels[i] as NxToolTipsNotePanel;					
					if(i==1)
					{
						temp.x = pos;
						pos += temp.width + 5;
					}
					else
					{
						temp.x = pos;
						pos += temp.width + 5;
					}
				}
				temp = NxToolTips.notePanels[0] as NxToolTipsNotePanel;
				temp.x = pos;
				normalState = false;
			}
			else
			{
				/** 回复正常显示 **/
				if(normalState)
				{
					return;
				}
				temp = NxToolTips.notePanels[npCount-1] as NxToolTipsNotePanel;
				temp.x = 0;
				pos += temp.width + 5;
				for(var j:int=0; j < npCount-1; ++j)
				{
					temp = NxToolTips.notePanels[j] as NxToolTipsNotePanel;
					temp.x = pos;
					pos += temp.width + 5;
				}
				normalState = true;
			}
		}
		
		private final function effIn(e:Event):void
		{
			resetPos();
		}
		
		/** @private 实例隐藏的方法 **/
		public final function hideText():void
		{
			this.removeEventListener(Event.ENTER_FRAME,		effIn);
			this.visible			=	false;
			return;
		}		
	}
}